home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-28 | 8.2 KB | 256 lines | [TEXT/ttxt] |
- This is the Pascal source of a public domain Pascal compiler and
- interpreter, the P4 compiler and interpreter. It is coded entirely in
- Pascal, and produces a high-level so-called intermediate code as
- output. The program 'pint' is an assembler and interpreter for this
- language.
-
- The entire compiler and interpreter is documented in the book:
- Pascal Implementation
- by Steven Pemberton and Martin Daniels
- published by Ellis Horwood, Chichester, UK.
- ISBN: 0-13-653-0311
- (also available in Japanese).
- It was distributed by John Wiley in other countries, but now that
- Prentice Hall has taken over Ellis Horwood, that will have changed.
-
- Steven Pemberton is contactable by email as Steven.Pemberton@cwi.nl.
-
- What you have to do to use this compiler:
-
- Compile pcom.p and pint.p with a Pascal compiler. You
- obviously have to have a Pascal compiler already. This gives
- you a Pascal compiler (pcom) that produces P4 code,
- and an interpreter (pint) that runs P4 code.
-
- To use the compiler, run pcom with the Pascal program as
- standard input. This produces any diagnostics on standard
- output, and its code on a Pascal file that is called prr.
- Check with your Pascal compiler how this gets assigned to a
- file in the filestore. You may have to change the lines
- 'rewrite(prr)' in pcom.p and pint.p and 'reset(prd)' in pint.p
- for your compiler, for instance to "rewrite(prr, 'prr')" etc.
-
- To run the resulting code, run pint with the prr output
- produced by pcom as input for the file 'prd', and input for
- the compiled pascal program on standard input.
-
- For instance, do this once:
- pc -o pcom pcom.p
- pc -o pint pint.c
- and for each program:
- pcom < test.p # produces file prr containing the p4 code
- mv prr prd
- pint < input
-
- You have to supply input to pint, even if the program doesn't
- read from it, for instance:
- pint < /dev/null
-
- If you intend to compile pcom with itself, there are two lines that
- have to be commented out when you do; search for the word 'comment' in
- the pcom source. There is no reason why you should want to compile
- pint.p with pcom.
-
- DIFFERENCES WITH THE BOOK
-
- The code here is slightly different from that in the book, but the
- line numbers have been kept the same. The changes were to allow
- modern Pascal compilers to compile the source (there were some
- laxities in the original code). The following are the changes:
-
- The type marktype is added for the parameters of the routines mark and
- release:
- 76c76
- <
- ---
- > marktype= ^integer;
-
- The type setty (which represents set types) is added for the new type
- compatibility rules of ISO Pascal:
- 95c95
- <
- ---
- > setty = set of setlow..sethigh;
- 100c100
- < pset: (pval: set of setlow..sethigh);
- ---
- > pset: (pval: setty);
-
- Missing variant parts:
- 123c123
- < declared: (fconst: ctp));
- ---
- > declared: (fconst: ctp); standard: ());
- 145a146
- > types: ();
- 149,150c150
- < proc,
- < func: (case pfdeckind: declkind of
- ---
- > proc, func: (case pfdeckind: declkind of
- 154,155c154,155
- < actual: (forwdecl, extern:
- < boolean)))
- ---
- > actual: (forwdecl, extern: boolean);
- > formal: ()))
-
- Pcom has the files prr and prd as standard identifiers. You have to
- declare them for other compilers:
- 193d192
- <
- 194a194
- > prr: text; (* comment this out when compiling with pcom *)
- 299d298
- <
-
- Other compilers don't have the routines mark and release. Their
- effective semantics are null; you just waste heap:
- 300a300,301
- > procedure mark(var p: marktype); begin end;
- > procedure release(p: marktype); begin end;
- 302d302
- <
-
- Output the line number with error messages, so that if the listing
- option has been switched off, you still know which line is in error:
- 307c307
- < begin write(output,' **** ':15);
- ---
- > begin write(output,linecount:6,' **** ':9);
-
- Accept tabs as white-space as well:
- 398c398
- < repeat while (ch = ' ') and not eol do nextch;
- ---
- > repeat while ((ch = ' ') or (ch = ' ')) and not eol do nextch;
-
- Jumping from the then part of an if into the else part is not allowed;
- fix cases like 1..10 in another way:
- 429c429
- < if (ch = '.') or (ch = 'e') then
- ---
- > if ((ch = '.') and (input^ <> '.')) or (ch = 'e') then
- 434c434
- < nextch; if ch = '.' then begin ch := ':'; goto 3 end;
- ---
- > nextch; (*if ch = '.' then begin ch := ':'; goto 3 end;*)
-
- Fix modern type mismatches:
- 668c668
- < procedure align(fsp: stp; var flc: integer);
- ---
- > procedure align(fsp: stp; var flc: addrrange);
-
- An identifier misspelled after the 8th character:
- 872c872
- < if sy = stringconstsy then
- ---
- > if sy = stringconst then
-
- Unused variables, and new type names:
- 1529,1531c1529,1531
- < var oldlev: 0..maxlevel; lsy: symbol; lcp,lcp1: ctp; lsp: stp;
- < forw: boolean; oldtop: disprange; parcnt: integer;
- < llc,lcm: addrrange; lbname: integer; markp: ^integer;
- ---
- > var oldlev: 0..maxlevel; lcp,lcp1: ctp; lsp: stp;
- > forw: boolean; oldtop: disprange;
- > llc,lcm: addrrange; lbname: integer; markp: marktype;
- 1535c1535
- < llc: addrrange; count,lsize: integer;
- ---
- > llc,lsize: addrrange; count: integer;
- 1819c1819
- < i, entname, segsize: integer;
- ---
- > entname, segsize: integer;
- 2087c2087
- < var lattr: attr; lcp: ctp; lsize,lmin,lmax: integer;
- ---
- > var lattr: attr; lcp: ctp; lsize: addrrange; lmin,lmax: integer;
- 2248c2248
- < var lcp:ctp; llev:levrange; laddr:addrrange;
- ---
- > var llev:levrange; laddr:addrrange;
- 2306c2306
- < lcp:ctp; llev:levrange; laddr,len:addrrange;
- ---
- > llev:levrange; laddr,len:addrrange;
- 2456,2457c2456,2457
- < var lsp,lsp1: stp; varts,lmin,lmax: integer;
- < lsize,lsz: addrrange; lval: valu;
- ---
- > var lsp,lsp1: stp; varts: integer;
- > lsize: addrrange; lval: valu;
- 2750c2750
- < cstpart: set of 0..47; lsp: stp;
- ---
- > cstpart: setty; lsp: stp;
-
- Unix pc can't cope with this line:
- 2926c2926
- < (*/*) rdiv: begin
- ---
- > (* / *) rdiv: begin
-
- More unused variables:
- 3318c3318
- < var lattr: attr; lsp: stp; lsy: symbol;
- ---
- > var lattr: attr; lsy: symbol;
- 3642c3642
- < var sp: stp;
- ---
- >
-
- Produce code as default:
- 3800c3800
- < prtables := false; list := true; prcode := false; debug := true;
- ---
- > prtables := false; list := true; prcode := true; debug := true;
-
- Unused variable:
- 3868c3868
- < var i: integer; ch: char;
- ---
- > var i: integer;
-
- Other compilers need to rewrite prr before using it:
- 3995,3996c3995,3996
- < (*compile:*)
- < (**********)
- ---
- > (*compile:*) rewrite(prr); (*comment this out when compiling with pcom *)
- > (**********)
-
- And all variables called 'extern' have been renamed to 'externl'.
-
- Differences in the interpreter are minimal:
-
- a set type has been added:
- 45a46
- > settype = set of 0..58;
- 63c64
- < sett :(vs :set of 0..47);
- ---
- > sett :(vs :settype);
- 225c226
- < var name :alfa; b :boolean; r :real; s :set of 0..58;
- ---
- > var name :alfa; b :boolean; r :real; s :settype;
-
- the initial writeln has been removed:
- 667c667
- < writeln(output); (* for testing *)
- ---
- > (* writeln(output); for testing *)
-
- and the type alfa has been added:
- 47c47
- <
- ---
- > alfa = packed array[1..10] of char;
-
- End of differences
-